package com.hn.project.rqinspect.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.hn.common.constant.RedisConstant;
import com.hn.common.enums.*;
import com.hn.common.exception.BusinessException;
import com.hn.common.utils.CommonUtils;
import com.hn.common.utils.OrderUtil;
import com.hn.common.utils.SecurityUtils;
import com.hn.common.utils.ding.DingNoticeUtil;
import com.hn.common.utils.sql.SqlUtil;
import com.hn.framework.redis.RedisCache;
import com.hn.framework.web.domain.AjaxResult;
import com.hn.project.rqinspect.domain.database.*;
import com.hn.project.rqinspect.domain.dto.*;
import com.hn.project.rqinspect.domain.vo.GenTaskVo;
import com.hn.project.rqinspect.domain.vo.QuesCheckRecordVo;
import com.hn.project.rqinspect.domain.vo.TaskRecordVo;
import com.hn.project.rqinspect.domain.vo.TaskVo;
import com.hn.project.rqinspect.mapper.*;
import com.hn.project.rqinspect.service.TaskCacheService;
import com.hn.project.rqinspect.service.TaskCheckService;
import com.hn.project.rqinspect.service.TaskService;
import com.hn.utils.AssertUtils;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
public class TaskServiceImpl implements TaskService {

    @Resource
    private TaskMapper taskMapper;

    @Autowired
    private TaskRecordMapper taskRecordMapper;

    @Autowired
    private TaskCheckRecordMapper taskCheckRecordMapper;

    @Autowired
    private TaskPushRecordMapper taskPushRecordMapper;

    @Autowired
    private SysUserMapper userMapper;

    @Autowired
    private TaskUserGroupMapper taskUserGroupMapper;

    @Autowired
    private UserBranchMapper userBranchMapper;

    @Autowired
    private BranchMapper branchMapper;

    @Autowired
    private UserGroupMapper userGroupMapper;

    @Autowired
    private TaskCacheService taskCacheService;

    @Value("${upload.web.url}")
    private String uploadWebUrl;

    @Override
    public Task get(Integer taskId) {
        return taskMapper.selectByPrimaryKey(taskId);
    }

    @Override
    public List<TaskRecordDto> listTodoTask(TaskRecordVo taskRecordVo) {
        List<TaskRecordDto> taskRecordDtos = taskRecordMapper.listTodoTask(taskRecordVo);
        for (TaskRecordDto taskRecordDto : taskRecordDtos) {
            String branchImgUrl = taskRecordDto.getBranchImgUrl();
            taskRecordDto.setBranchImgUrl(CommonUtils.pingJieUrl(branchImgUrl, uploadWebUrl));
        }
        return taskRecordDtos;
    }

    @Override
    public List<TaskRecordHistoryDto> listHistoryTaskRecord(TaskRecordVo taskRecordVo) {
        List<TaskRecordHistoryDto> taskRecordHistoryDtos = taskRecordMapper.listHistoryTaskRecord(taskRecordVo);

        for (TaskRecordHistoryDto taskRecordHistoryDto : taskRecordHistoryDtos) {
            Integer taskRecordId = taskRecordHistoryDto.getTaskRecordId();
            // 获取检查部位个数
            Integer checkPartNum = taskCheckRecordMapper.countCheckPartNum(taskRecordId, SubmitStatusEnum.YES.status);
            taskRecordHistoryDto.setCheckPartNum(checkPartNum);

            TaskCheckRecord query = new TaskCheckRecord();
            query.setTaskRecordId(taskRecordId);
            query.setSubmitStatus(SubmitStatusEnum.YES.status);
            query.setCommentType(CommentTypeEnum.BAD.type);
            //  检出问题个数
            Integer checkQuesNum = taskCheckRecordMapper.selectCountByExample(SqlUtil.newExample(query));
            taskRecordHistoryDto.setCheckQuesNum(checkQuesNum);

            // 待整改问题个数
            query.setFollowStatus(FollowStatusEnum.CHANGE.status);
            Integer checkChangeNum = taskCheckRecordMapper.selectCountByExample(SqlUtil.newExample(query));
            taskRecordHistoryDto.setCheckChangeNum(checkChangeNum);

            // 已处理问题个数
            query.setFollowStatus(FollowStatusEnum.SUCCESS.status);
            Integer processQuesNum = taskCheckRecordMapper.selectCountByExample(SqlUtil.newExample(query));
            taskRecordHistoryDto.setProcessQuesNum(processQuesNum);

            // 高风险个数
            query.setFollowStatus(FollowStatusEnum.CHANGE.status);
            query.setRiskEvaluation(RiskLevelEnum.HIGH.level);
            int highRiskLevelNum = taskCheckRecordMapper.selectCountByExample(SqlUtil.newExample(query));
            taskRecordHistoryDto.setHighRiskLevelNum(highRiskLevelNum);

            // 中风险个数
            query.setRiskEvaluation(RiskLevelEnum.SECOND.level);
            int secondRiskLevelNum = taskCheckRecordMapper.selectCountByExample(SqlUtil.newExample(query));
            taskRecordHistoryDto.setSecondRiskLevelNum(secondRiskLevelNum);

            // 低风险个数
            query.setRiskEvaluation(RiskLevelEnum.LOW.level);
            int lowRiskLevelNum = taskCheckRecordMapper.selectCountByExample(SqlUtil.newExample(query));
            taskRecordHistoryDto.setLowRiskLevelNum(lowRiskLevelNum);

            if (highRiskLevelNum > 0) {
                taskRecordHistoryDto.setRiskLevel(RiskLevelEnum.HIGH.level);
            } else if (secondRiskLevelNum > 0) {
                taskRecordHistoryDto.setRiskLevel(RiskLevelEnum.SECOND.level);
            } else if (lowRiskLevelNum > 0) {
                taskRecordHistoryDto.setRiskLevel(RiskLevelEnum.LOW.level);
            } else {
                taskRecordHistoryDto.setRiskLevel(RiskLevelEnum.SECURITY.level);
            }

            String otherCheckUserIds = taskRecordHistoryDto.getOtherCheckUserIds();
            String checkUserName = taskRecordHistoryDto.getCheckUserName();
            if (StrUtil.isNotBlank(otherCheckUserIds)) {
                String userNames = userMapper.getUserNamesByUserIds(otherCheckUserIds);
                checkUserName = checkUserName + "," + userNames;
            }
            taskRecordHistoryDto.setCheckUserName(checkUserName);
        }
        return taskRecordHistoryDtos;
    }

    @Override
    public TaskRecordHistoryDto getHistoryTaskRecord(Integer taskRecordId) {
        TaskRecordHistoryDto taskRecordHistoryDto = taskRecordMapper.getHistoryTaskRecord(taskRecordId);
        if (taskRecordHistoryDto != null) {
            // 获取检查部位个数
            Integer checkPartNum = taskCheckRecordMapper.countCheckPartNum(taskRecordId, SubmitStatusEnum.YES.status);
            taskRecordHistoryDto.setCheckPartNum(checkPartNum);

            Integer checkPartBadNum = taskCheckRecordMapper.countCheckPartBadNum(taskRecordId, SubmitStatusEnum.YES.status);
            taskRecordHistoryDto.setCheckPartBadNum(checkPartBadNum);

            TaskCheckRecord query = new TaskCheckRecord();
            query.setTaskRecordId(taskRecordId);
            query.setSubmitStatus(SubmitStatusEnum.YES.status);
            query.setCommentType(CommentTypeEnum.BAD.type);
            // 检出问题个数
            Integer checkQuesNum = taskCheckRecordMapper.selectCountByExample(SqlUtil.newExample(query));
            taskRecordHistoryDto.setCheckQuesNum(checkQuesNum);

            // 待整改问题个数
            query.setFollowStatus(FollowStatusEnum.CHANGE.status);
            Integer checkChangeNum = taskCheckRecordMapper.selectCountByExample(SqlUtil.newExample(query));
            taskRecordHistoryDto.setCheckChangeNum(checkChangeNum);

            // 已处理问题个数
            query.setFollowStatus(FollowStatusEnum.SUCCESS.status);
            Integer processQuesNum = taskCheckRecordMapper.selectCountByExample(SqlUtil.newExample(query));
            taskRecordHistoryDto.setProcessQuesNum(processQuesNum);

            // 高风险个数
            query.setFollowStatus(FollowStatusEnum.CHANGE.status);
            query.setRiskEvaluation(RiskLevelEnum.HIGH.level);
            int highRiskLevelNum = taskCheckRecordMapper.selectCountByExample(SqlUtil.newExample(query));
            taskRecordHistoryDto.setHighRiskLevelNum(highRiskLevelNum);

            // 中风险个数
            query.setRiskEvaluation(RiskLevelEnum.SECOND.level);
            int secondRiskLevelNum = taskCheckRecordMapper.selectCountByExample(SqlUtil.newExample(query));
            taskRecordHistoryDto.setSecondRiskLevelNum(secondRiskLevelNum);

            // 低风险个数
            query.setRiskEvaluation(RiskLevelEnum.LOW.level);
            int lowRiskLevelNum = taskCheckRecordMapper.selectCountByExample(SqlUtil.newExample(query));
            taskRecordHistoryDto.setLowRiskLevelNum(lowRiskLevelNum);

            if (highRiskLevelNum > 0) {
                taskRecordHistoryDto.setRiskLevel(RiskLevelEnum.HIGH.level);
            } else if (secondRiskLevelNum > 0) {
                taskRecordHistoryDto.setRiskLevel(RiskLevelEnum.SECOND.level);
            } else if (lowRiskLevelNum > 0) {
                taskRecordHistoryDto.setRiskLevel(RiskLevelEnum.LOW.level);
            } else {
                taskRecordHistoryDto.setRiskLevel(RiskLevelEnum.SECURITY.level);
            }

            String otherCheckUserIds = taskRecordHistoryDto.getOtherCheckUserIds();
            String checkUserName = taskRecordHistoryDto.getCheckUserName();
            if (StrUtil.isNotBlank(otherCheckUserIds)) {
                String userNames = userMapper.getUserNamesByUserIds(otherCheckUserIds);
                checkUserName = checkUserName + "," + userNames;
            }
            taskRecordHistoryDto.setCheckUserName(checkUserName);

        }
        return taskRecordHistoryDto;
    }

    @Override
    public TaskRecordDto getTaskRecord(Integer pushRecordId) {
        return taskRecordMapper.getTaskRecord(pushRecordId);
    }

    @Override
    public int updateTaskRecord(TaskRecord taskRecord) {
        taskRecord.setUpdateTime(DateUtil.date());
        return taskRecordMapper.updateByPrimaryKeySelective(taskRecord);
    }

    @Override
    @Transactional
    public int submit(Integer taskRecordId) {
        TaskRecord taskRecord = taskRecordMapper.selectByPrimaryKey(taskRecordId);
        if (taskRecord == null) {
            throw new BusinessException("巡检日记不存在");
        }

        Integer submitStatus = taskRecord.getSubmitStatus();
        if (SubmitStatusEnum.YES.status.equals(submitStatus)) {
            throw new BusinessException("请勿重复提交");
        }

        Integer taskId = taskRecord.getTaskId();
        Task task = taskMapper.selectByPrimaryKey(taskId);
        Integer totalPartNum = taskCheckRecordMapper.countTotalPartNum(taskRecord.getBranchId(), task.getQuesId());

        // 当每个部位的巡检信息大于1条时，方可提交为巡检报告。否则提示“您的本次巡检尚有未巡检的部位，无法提交巡检报告。请继续巡检或左上角退出保存。“
        Integer checkPartNum = taskCheckRecordMapper.countCheckPartNum(taskRecordId, SubmitStatusEnum.NO.status);
        if (checkPartNum < totalPartNum) {
            throw new BusinessException("您的本次巡检尚有未巡检的部位，无法提交巡检报告。请继续巡检或存草稿暂不提交。");
        }

        taskRecord.setSubmitStatus(SubmitStatusEnum.YES.status);
        DateTime nowDate = DateUtil.date();
        taskRecord.setSubmitTime(nowDate);
        taskRecord.setUpdateTime(nowDate);
        taskRecord.setStatus(TaskRecordStatusEnum.FINISH.status);
        int rows = taskRecordMapper.updateByPrimaryKeySelective(taskRecord);

        taskCheckRecordMapper.submitTaskCheckRecord(taskRecordId, nowDate);

        saveNewQuesCache(taskRecordId, taskRecord.getBranchId());

        // todo 剩余检查点改为合格？

        return rows;
    }

    /**
     * 存储缓存 -> 新问题
     */
    private void saveNewQuesCache(Integer taskRecordId, Integer branchId) {
        TaskCheckRecord qCheckRecord = new TaskCheckRecord();
        qCheckRecord.setTaskRecordId(taskRecordId);
        List<TaskCheckRecord> taskCheckRecords = taskCheckRecordMapper.selectByExample(SqlUtil.newExample(qCheckRecord));

        // 查询网点负责人
        List<Integer> userIds = userBranchMapper.listUserIdsByBranchId(branchId, RoleIdEnum.BRANCH.id);
        if (userIds == null || userIds.isEmpty()) {
            return;
        }

        for (TaskCheckRecord taskCheckRecord : taskCheckRecords) {
            for (Integer userId : userIds) {
                taskCacheService.add(RedisConstant.CHECK_CHANGE_QUES, userId, taskCheckRecord.getId());
            }
        }

    }

    @Override
    public List<Integer> listGenTask(List<Integer> groupIds, List<Integer> branchIds) {
        return taskMapper.listGenTask(groupIds, branchIds);
    }

    @Override
    public int genTaskPushRecord(List<TaskPushRecord> taskPushRecords) {
        return taskRecordMapper.genTaskPushRecord(taskPushRecords);
    }

    @Override
    public int saveTaskRecord(TaskRecord taskRecord) {
        Integer pushRecordId = taskRecord.getPushRecordId();
        TaskPushRecord taskPushRecord = taskPushRecordMapper.selectByPrimaryKey(pushRecordId);
        Integer taskRecordId = taskPushRecord.getTaskRecordId();
        if (taskRecordId == null) {
            DateTime date = DateUtil.date();
            taskRecord.setRecordCode(OrderUtil.orderNO());
            taskRecord.setCheckTime(date);
            taskRecord.setCreateTime(date);
            taskRecord.setTaskId(taskPushRecord.getTaskId());
            taskRecord.setBranchId(taskPushRecord.getBranchId());
            taskRecord.setStatus(1);
            taskRecord.setSubmitStatus(0);
            int rows = taskRecordMapper.insertSelective(taskRecord);

            if (rows > 0) {
                TaskPushRecord pushRecord = new TaskPushRecord();
                pushRecord.setId(taskRecord.getPushRecordId());
                pushRecord.setTaskRecordId(taskRecord.getId());
                pushRecord.setUpdateTime(date);
                taskPushRecordMapper.updateByPrimaryKeySelective(pushRecord);

                // 更新其他巡检员的任务推送记录的状态
                String otherCheckUserIds = taskRecord.getOtherCheckUserIds();
                if (StrUtil.isNotBlank(otherCheckUserIds)) {
                    String[] otherUserIds = otherCheckUserIds.split(",");
                    taskPushRecordMapper.update(otherUserIds, taskRecord.getTaskId(), taskPushRecord.getBranchId(),
                            taskPushRecord.getCreateTime(), taskRecord.getId());
                }

                // 钉钉去除待办
                String dingRecordId = taskPushRecord.getDingRecordId();
                if (StrUtil.isNotBlank(dingRecordId)) {
                    SysUser user = userMapper.selectByPrimaryKey(taskRecord.getCheckUserId());
                    if (user != null) {
                        DingNoticeUtil.updateWorkRecord(user.getDingId(), dingRecordId);
                    }
                    taskPushRecord.setDingRecordId(null);
                    taskPushRecordMapper.updateByPrimaryKey(taskPushRecord);
                }
            }
        } else {
            taskRecord.setId(taskRecordId);
            taskRecord.setUpdateTime(DateUtil.date());
            taskRecordMapper.updateByPrimaryKeySelective(taskRecord);
        }

        return taskRecord.getId();
    }

    @Override
    public List<CheckUserDto> listCheckUsers(Integer taskId, Integer userId) {
        List<Integer> groupIds = taskUserGroupMapper.listGroupIdsByTaskId(taskId);
        return taskUserGroupMapper.listCheckUsers(groupIds, userId);
    }

    @Override
    public TaskCheckCountDto countTaskCheckRecord(Integer branchId) {
        TaskCheckCountDto taskCheckCountDto = new TaskCheckCountDto();
        List<TaskCheckRecord> taskCheckRecords = taskCheckRecordMapper.listCheckRecordByBranchId(branchId);
        //  检出的问题 高风险
        int highRiskLevelNum = 0;
        //  检出的问题 中风险
        int secondRiskLevelNum = 0;
        //  检出的问题 低风险
        int lowRiskLevelNum = 0;

        //  未处理的问题 高风险
        int noHighRiskLevelNum = 0;
        //  未处理的问题 中风险
        int noSecondRiskLevelNum = 0;
        //  未处理的问题 低风险
        int noLowRiskLevelNum = 0;

        for (TaskCheckRecord taskCheckRecord : taskCheckRecords) {
            Integer riskEvaluation = taskCheckRecord.getRiskEvaluation();

            Integer followStatus = taskCheckRecord.getFollowStatus();

            if (FollowStatusEnum.CHANGE.status.equals(followStatus)) {
                if (RiskLevelEnum.HIGH.level.equals(riskEvaluation)) {
                    highRiskLevelNum += 1;
                } else if (RiskLevelEnum.SECOND.level.equals(riskEvaluation)) {
                    secondRiskLevelNum += 1;
                } else {
                    lowRiskLevelNum += 1;
                }
            } else {
                if (RiskLevelEnum.HIGH.level.equals(riskEvaluation)) {
                    noHighRiskLevelNum += 1;
                } else if (RiskLevelEnum.SECOND.level.equals(riskEvaluation)) {
                    noSecondRiskLevelNum += 1;
                } else {
                    noLowRiskLevelNum += 1;
                }
            }
        }
        taskCheckCountDto.setHighRiskLevelNum(highRiskLevelNum);
        taskCheckCountDto.setSecondRiskLevelNum(secondRiskLevelNum);
        taskCheckCountDto.setLowRiskLevelNum(lowRiskLevelNum);
        taskCheckCountDto.setNoHighRiskLevelNum(noHighRiskLevelNum);
        taskCheckCountDto.setNoSecondRiskLevelNum(noSecondRiskLevelNum);
        taskCheckCountDto.setNoLowRiskLevelNum(noLowRiskLevelNum);
        return taskCheckCountDto;
    }

    @Override
    public CountTodoTaskDto countTodoTask(List<Integer> groupIds) {
        CountTodoTaskDto countTodoTaskDto = new CountTodoTaskDto();
        // 获取分组下的任务
        List<Integer> taskIds = taskUserGroupMapper.listTaskIdsByGroupIds(groupIds);
        if (taskIds == null || taskIds.isEmpty()) {
            return countTodoTaskDto;
        }

        Integer userId = SecurityUtils.getUserId();
        Integer cadreTaskNum = taskRecordMapper.countTodoTask(taskIds, TaskTypeEnum.CADRE.type, userId);
        Integer specialTaskNu = taskRecordMapper.countTodoTask(taskIds, TaskTypeEnum.SPECIAL.type, userId);
        Integer branchTaskNum = taskRecordMapper.countTodoTask(taskIds, TaskTypeEnum.BRANCH.type, userId);
        countTodoTaskDto.setCadreTaskNum(cadreTaskNum);
        countTodoTaskDto.setSpecialTaskNum(specialTaskNu);
        countTodoTaskDto.setBranchTaskNum(branchTaskNum);

        return countTodoTaskDto;
    }

    @Override
    public List<Integer> listTaskIdsByGroupIds(List<Integer> groupIds) {
        return taskUserGroupMapper.listTaskIdsByGroupIds(groupIds);
    }

    @Override
    public List<Integer> listTaskIdsByBranchIds(List<Integer> branchIds) {
        return taskUserGroupMapper.listTaskIdsByBranchIds(branchIds);
    }

    @Override
    public CountTaskNumDto countTask(Integer userId) {
        // 获取当前用户管理的网点
        List<Integer> branchIds = userBranchMapper.listBranchIdsByUserId(userId);
        CountTaskNumDto countTaskNumDto = new CountTaskNumDto();
        if (branchIds.isEmpty()) {
            return countTaskNumDto;
        }

        // 获取分组下的任务
        List<Integer> taskIds = taskUserGroupMapper.listTaskIdsByBranchIds(branchIds);
        if (taskIds == null || taskIds.isEmpty()) {
            return countTaskNumDto;
        }

        Integer cadreTaskNum = taskMapper.countTask(taskIds, TaskTypeEnum.CADRE.type);
        Integer specialTaskNu = taskMapper.countTask(taskIds, TaskTypeEnum.SPECIAL.type);
        Integer branchTaskNum = taskMapper.countTask(taskIds, TaskTypeEnum.BRANCH.type);
        countTaskNumDto.setCadreTaskNum(cadreTaskNum);
        countTaskNumDto.setSpecialTaskNum(specialTaskNu);
        countTaskNumDto.setBranchTaskNum(branchTaskNum);

        return countTaskNumDto;
    }

    @Override
    public CountTaskDto countTaskRecord(Integer userId, Integer taskId) {
        // 获取当前用户管理的网点
        List<Integer> branchIds = userBranchMapper.listBranchIdsByUserId(userId);
        CountTaskDto countTaskDto = new CountTaskDto();
        if (branchIds.isEmpty()) {
            return countTaskDto;
        }

        Integer todoTaskNum = taskRecordMapper.countTaskNum(branchIds, taskId, TaskRecordStatusEnum.TODO.status);
        Integer finishTaskNum = taskRecordMapper.countTaskNum(branchIds, taskId, TaskRecordStatusEnum.FINISH.status);
        Integer unfinishTaskNum = taskRecordMapper.countTaskNum(branchIds, taskId, TaskRecordStatusEnum.FAIL.status);
        countTaskDto.setFinishTaskNum(finishTaskNum);
        countTaskDto.setUnfinishTaskNum(unfinishTaskNum);
        countTaskDto.setTodoTaskNum(todoTaskNum);
        return countTaskDto;
    }

    @Override
    public CountTaskNumDto countFinishTask(Integer userId, Integer roleType) {
        CountTaskNumDto countTaskNumDto = new CountTaskNumDto();
        if (RoleTypeEnum.BRANCH.type.equals(roleType)) {
            // 获取当前用户管理的网点
            List<Integer> branchIds = userBranchMapper.listBranchIdsByUserId(userId);
            if (branchIds.isEmpty()) {
                return countTaskNumDto;
            }
            countTaskNumDto.setSpecialTaskNum(taskRecordMapper.countFinishTaskNumByBranchIds(branchIds, TaskTypeEnum.SPECIAL.type));
            countTaskNumDto.setBranchTaskNum(taskRecordMapper.countFinishTaskNumByBranchIds(branchIds, TaskTypeEnum.BRANCH.type));
            countTaskNumDto.setCadreTaskNum(taskRecordMapper.countFinishTaskNumByBranchIds(branchIds, TaskTypeEnum.CADRE.type));
        } else {
            countTaskNumDto.setSpecialTaskNum(taskRecordMapper.countFinishTaskNumByUserId(userId, TaskTypeEnum.SPECIAL.type));
            countTaskNumDto.setBranchTaskNum(taskRecordMapper.countFinishTaskNumByUserId(userId, TaskTypeEnum.BRANCH.type));
            countTaskNumDto.setCadreTaskNum(taskRecordMapper.countFinishTaskNumByUserId(userId, TaskTypeEnum.CADRE.type));
        }

        return countTaskNumDto;
    }

    @Override
    public CountTaskNumDto countQuesTask(Integer userId) {
        CountTaskNumDto countTaskNumDto = new CountTaskNumDto();

        QuesCheckRecordVo quesCheckRecordVo = new QuesCheckRecordVo();
        quesCheckRecordVo.setUserId(userId);

        quesCheckRecordVo.setTaskType(TaskTypeEnum.CADRE.type);
        countTaskNumDto.setCadreTaskNum(taskCheckRecordMapper.countQuesCheckRecord(quesCheckRecordVo));

        quesCheckRecordVo.setTaskType(TaskTypeEnum.SPECIAL.type);
        countTaskNumDto.setSpecialTaskNum(taskCheckRecordMapper.countQuesCheckRecord(quesCheckRecordVo));

        quesCheckRecordVo.setTaskType(TaskTypeEnum.BRANCH.type);
        countTaskNumDto.setBranchTaskNum(taskCheckRecordMapper.countQuesCheckRecord(quesCheckRecordVo));
        return countTaskNumDto;
    }

    @Override
    public CountTaskNumDto countBranchQuesTask(Integer userId) {
        CountTaskNumDto countTaskNumDto = new CountTaskNumDto();
        List<Integer> branchIds = userBranchMapper.listBranchIdsByUserId(userId);
        if (branchIds == null) {
            return countTaskNumDto;
        }

        QuesCheckRecordVo quesCheckRecordVo = new QuesCheckRecordVo();
        quesCheckRecordVo.setBranchIds(branchIds);

        quesCheckRecordVo.setTaskType(TaskTypeEnum.SPECIAL.type);
        countTaskNumDto.setSpecialTaskNum(taskCheckRecordMapper.countQuesCheckRecord(quesCheckRecordVo));

        quesCheckRecordVo.setTaskType(TaskTypeEnum.BRANCH.type);
        countTaskNumDto.setBranchTaskNum(taskCheckRecordMapper.countQuesCheckRecord(quesCheckRecordVo));

        quesCheckRecordVo.setTaskType(TaskTypeEnum.CADRE.type);
        countTaskNumDto.setCadreTaskNum(taskCheckRecordMapper.countQuesCheckRecord(quesCheckRecordVo));

        return countTaskNumDto;
    }

    @Override
    public CountTaskNumDto countDraftTask(Integer userId) {
        CountTaskNumDto countTaskNumDto = new CountTaskNumDto();
        Integer cadreNum = taskRecordMapper.countDraftTaskNumByUserId(userId, TaskTypeEnum.CADRE.type);
        Integer branchNum = taskRecordMapper.countDraftTaskNumByUserId(userId, TaskTypeEnum.BRANCH.type);
        Integer specialNum = taskRecordMapper.countDraftTaskNumByUserId(userId, TaskTypeEnum.SPECIAL.type);
        countTaskNumDto.setCadreTaskNum(cadreNum);
        countTaskNumDto.setSpecialTaskNum(specialNum);
        countTaskNumDto.setBranchTaskNum(branchNum);
        return countTaskNumDto;
    }

    @Override
    public CountTaskNumDto countAuditSuccessTask(Integer userId) {
        List<Integer> branchIds = userBranchMapper.listBranchIdsByUserId(userId);
        CountTaskNumDto countTaskNumDto = new CountTaskNumDto();
        if (branchIds == null) {
            return countTaskNumDto;
        }
        int cadreNum = taskRecordMapper.countAuditSuccessTask(branchIds, TaskTypeEnum.CADRE.type);
        countTaskNumDto.setCadreTaskNum(cadreNum);
        int branchNum = taskRecordMapper.countAuditSuccessTask(branchIds, TaskTypeEnum.BRANCH.type);
        countTaskNumDto.setBranchTaskNum(branchNum);
        int specialNum = taskRecordMapper.countAuditSuccessTask(branchIds, TaskTypeEnum.SPECIAL.type);
        countTaskNumDto.setSpecialTaskNum(specialNum);

        return countTaskNumDto;
    }

    @Override
    public CountTaskNumDto countAuditTodoTask(Integer userId) {
        List<Integer> branchIds = userBranchMapper.listBranchIdsByUserId(userId);
        CountTaskNumDto countTaskNumDto = new CountTaskNumDto();
        if (branchIds == null) {
            return countTaskNumDto;
        }
        int cadreNum = taskRecordMapper.countAuditTodoTask(branchIds, TaskTypeEnum.CADRE.type);
        countTaskNumDto.setCadreTaskNum(cadreNum);
        int branchNum = taskRecordMapper.countAuditTodoTask(branchIds, TaskTypeEnum.BRANCH.type);
        countTaskNumDto.setBranchTaskNum(branchNum);
        int specialNum = taskRecordMapper.countAuditTodoTask(branchIds, TaskTypeEnum.SPECIAL.type);
        countTaskNumDto.setSpecialTaskNum(specialNum);

        return countTaskNumDto;
    }

    @Override
    public List<DraftTaskDto> listDraftTask(Integer userId, Integer taskType) {
        List<DraftTaskDto> draftTaskDtos = taskRecordMapper.listDraftTask(userId, taskType);
        for (DraftTaskDto draftTaskDto : draftTaskDtos) {
            Integer taskRecordId = draftTaskDto.getTaskRecordId();
            // 获取巡检部位总个数
            Integer totalPartNum = taskCheckRecordMapper.countTotalPartNum(draftTaskDto.getBranchId(), draftTaskDto.getQuesId());
            // 已完成部位个数
            Integer finishPartNum = taskCheckRecordMapper.countFinishPartNum(taskRecordId);
            draftTaskDto.setTotalPartNum(totalPartNum);
            draftTaskDto.setFinishPartNum(finishPartNum);
        }
        return draftTaskDtos;
    }

    @Override
    public CountSubmitBeforeDto countSubmitBefore(Integer taskRecordId) {
        Integer checkPartNum = taskCheckRecordMapper.countCheckPartNum(taskRecordId, SubmitStatusEnum.NO.status);
        Integer quesCheckPartNum = taskCheckRecordMapper.countCheckPartBadNum(taskRecordId, SubmitStatusEnum.NO.status);

        CountSubmitBeforeDto countSubmitBeforeDto = new CountSubmitBeforeDto();
        countSubmitBeforeDto.setCheckPartNum(checkPartNum);
        countSubmitBeforeDto.setQuesCheckPartNum(quesCheckPartNum);
        return countSubmitBeforeDto;
    }

    @Override
    public List<TaskDto> listTask(TaskVo taskVo) {
        return taskMapper.listTask(taskVo);
    }

    @Override
    public List<TaskRecordDto> listTaskRecord(TaskRecordVo taskRecordVo) {
        return taskRecordMapper.listTaskRecord(taskRecordVo);
    }

    @Override
    public int receiveTaskRecord(Integer pushRecordId) {
        TaskPushRecord taskPushRecord = taskPushRecordMapper.selectByPrimaryKey(pushRecordId);
        AssertUtils.notNull(taskPushRecord, "任务不存在");
        Integer taskRecordId = taskPushRecord.getTaskRecordId();
        AssertUtils.isTrue(taskRecordId == null, "任务已被其他人领取");

        TaskRecord taskRecord = new TaskRecord();
        Integer userId = SecurityUtils.getUserId();
        taskRecord.setCheckUserId(userId);
        DateTime date = DateUtil.date();
        taskRecord.setRecordCode(OrderUtil.orderNO());
        taskRecord.setTaskId(taskPushRecord.getTaskId());
        taskRecord.setBranchId(taskPushRecord.getBranchId());
        taskRecord.setStatus(1);
        taskRecord.setSubmitStatus(0);
        taskRecord.setCheckTime(date);
        taskRecord.setCreateTime(date);
        taskRecordMapper.insertSelective(taskRecord);

        TaskPushRecord pushRecord = new TaskPushRecord();
        pushRecord.setId(pushRecordId);
        pushRecord.setTaskRecordId(taskRecord.getId());
        pushRecord.setUpdateTime(date);
        pushRecord.setUserId(userId);
        return taskPushRecordMapper.updateByPrimaryKeySelective(pushRecord);
    }

    @Override
    public List<TaskRecord> listGenTaskRecord(List<Integer> taskIds, Integer userId) {
        return taskRecordMapper.listGenTaskRecord(taskIds, userId);
    }

    @Override
    public AjaxResult genTask(String lng, String lat, Integer userId) {
        Branch branch = branchMapper.getBranchByPosition(lng, lat);
        if (branch == null) {
            return AjaxResult.error(404, "无任务");
        }

        //  查询当前用户所在的分组
        List<Integer> groupIds = userGroupMapper.listGroupIdsByUserId(userId);
        if (groupIds == null || groupIds.isEmpty()) {
            return AjaxResult.error(404, "无任务");
        }

        List<Integer> branchIds = new ArrayList<>();
        branchIds.add(branch.getId());

        //  查询任务
        List<Integer> taskIds = listGenTask(groupIds, branchIds);
        if (taskIds.isEmpty()) {
            return AjaxResult.error(404, "无任务");
        }

        // 查询当前是否已经生成了任务,今天是否已经完成了任务
        List<TaskRecord> taskRecords = listGenTaskRecord(taskIds, userId);

        if (taskRecords != null && !taskRecords.isEmpty()) {
            return AjaxResult.error(404, "无任务");
        }

        List<TaskPushRecord> taskPushRecords = new ArrayList<>();
        DateTime nowDate = DateUtil.date();
        for (Integer taskId : taskIds) {
            Task task = get(taskId);

            TaskPushRecord taskPushRecord = new TaskPushRecord();
            taskPushRecord.setTaskId(taskId);
            taskPushRecord.setBranchId(branch.getId());
            taskPushRecord.setUserId(userId);
            taskPushRecord.setRecordCode(OrderUtil.orderNO());
            taskPushRecord.setEndTime(DateUtil.offsetDay(nowDate, task.getDays()));
            taskPushRecords.add(taskPushRecord);
        }

        if (taskPushRecords.isEmpty()) {
            return AjaxResult.error(404, "无任务");
        }

        // 生成推送任务记录
        genTaskPushRecord(taskPushRecords);

        // 返回第一个
        TaskPushRecord taskPushRecord = taskPushRecords.get(0);
        GenTaskDto genTaskDto = new GenTaskDto();
        genTaskDto.setPushRecordId(taskPushRecord.getId());
        genTaskDto.setBranchId(taskPushRecord.getBranchId());
        genTaskDto.setBranchName(branch.getName());
        genTaskDto.setLat(branch.getLat());
        genTaskDto.setLng(branch.getLng());
        return AjaxResult.success(genTaskDto);
    }
}
